Міністерство освіти і науки України
Національний університет «Львівська політехніка»
Інститут комп’ютерних наук та інформаційних технологій
Кафедра автоматизованих систем управління
Лабораторна робота №5
З курсу:
«Комп’ютерна графіка»
Тема: Метод цифрового диференціального аналізатора.
Мета: Освоїти розкладання відрізка в растр методом цифрового диференціального аналізатора.
.
ТЕОРЕТИЧНІ ОСНОВИ
Один з методів розкладання відрізка в растр полягає в розв’язуванні диференціального рівняння, що описує цей процес. Для прямої лінії маємо dy/dX=const Dy/DX=(y2 – y1)/(x2 -Xl)
Розв’язок представляється у вигляді
yі+1 =yi+Dy yі+1 = yi +Dx(y2-yl)/(x2-xl)
де х1 , у1 i х2 , у2 - кінці відрізка, що розкладається, i уі - початкове значення для чергового кроку вздовж відрізка. Фактично рівняння являє собою рекурентне співвідношення для послідовних значень у вздовж потрібного відрізка. Цей метод, використовуваний для розкладання в растр відрізків, називається цифровим диференціальним аналізатором (ЦДА). У простому ЦДА або Dx, або Dy (більше iз збільшень) вибирається як одиниця растра. Нижче наводиться простий алгоритм, що працює у вcix квадрантах:
Процедура розкладання в растр відрізка по методу цифрового диференціального аналізатора
Передбачається, що кінці відрізка (х1 у1) i (х2 у2) не збігаються
Апроксимуємо довжину відрізка
if abs(x2-xl)>=abs(y2-yl) then
Довжина= abs (х2-х1)
else Довжина= abs (у2-у1)
End { if }
назначаемо більше iз збільшень Dx чи Dy рівним одиниці растра
Dx =(х2-х1)/Довжина
Dy = (y2-yl )/Довжина
округляємо величини, а не відкидаємо дробову частину
використання знакової функції робить алгоритм придатним для вcix квадрантів
x= х1; y= yl;
Plot (round(x), round(y)) //промалювання пікселя
початок основного циклу i=l
while (i=Довжина) do x=x+Dx; y=y+Dy; i=i+l;
Plot (round(x), round(y)); End
Текст програмного коду:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, StdCtrls, ExtCtrls,math;
type
TForm1 = class(TForm)
StringGrid1: TStringGrid;
StringGrid2: TStringGrid;
Button1: TButton;
Image1: TImage;
Label1: TLabel;
Label2: TLabel;
procedure Button1Click(Sender: TObject);
procedure koord();
procedure draw_P(x_k,y_k:integer);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
x0,y0,delta:integer;
implementation
procedure TForm1.koord();
var delta_p,x1,x2,x3,x4,y1,y2,y3,y4,i:integer;
begin
x0:=round(image1.Width/2);
y0:=round((image1.Height)/2);
with image1.Canvas do
begin
if (image1.Width-x0)>(image1.Height-y0) then
delta:=round((image1.Height-y0)/10)
else
delta:=round((image1.Width-x0)/10);
x1:=x0;
x2:=x0;
x3:=x0;
x4:=x0;
y1:=y0;
y2:=y0;
y3:=y0;
y4:=y0;
for i:=0 to 30 do begin
delta_p:=delta;
MoveTo(x0,y1);
LineTo(x0,y1-delta_p);
moveto(x0-2,y1-delta_p);
LineTo (x0+2,y1-delta_p);
y1:=y1-delta_p;
MoveTo(x0,y2);
LineTo(x0,y2+delta_p);
moveto(x0-2,y2+delta_p);
LineTo (x0+2,y2+delta_p);
y2:=y2+delta_p;
MoveTo(x3,y0);
LineTo(x3+delta_p,y0);
moveto(x3+delta_p,y0-2);
LineTo (x3+delta_p,y0+2);
x3:= x3+delta_p;
MoveTo(x4,y0);
LineTo(x4-delta_p,y0);
moveto(x4-delta_p,y0-2);
LineTo (x4-delta_p,y0+2);
x4:= x4-delta_p;
end;
x1:=x0;
x2:=x0;
x3:=0;
x4:=x0;
y1:=Image1.Height;
y2:=y0;
y3:=y0;
y4:=y0;
for i:=0 to 30 do begin
delta_p:=delta;
pen.Style:=psDot;
moveto(0,y1-delta_p);
LineTo (image1.Width,y1-delta_p);
moveto(x3+delta_p,0);
LineTo (x3+delta_p,image1.Height);
y1:=y1-delta_p;
x3:= x3+delta_p;
end;
end;
end;
procedure TForm1.draw_P(x_k,y_k:integer);
var xx,yy,col:integer;
begin
with image1.Canvas do
begin
pen....